/**
 * Copyright (C) 2012 The SkyTvOS Project
 * <p/>
 * Version     Date           Author
 * ─────────────────────────────────────
 * 2014年12月20日         Root.Lu
 */

package com.coocaa.launcher.framework.launcherhost;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.Intent.ShortcutIconResource;
import android.content.IntentFilter;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Parcelable;
import android.view.KeyEvent;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.coocaa.launcher.framework.launcherhost.LauncherHostView.LauncherHostPageView;
import com.coocaa.launcher.framework.launcherhost.LauncherHostViewBoundaryEvent.IHostViewBoundaryEventHandler;
import com.coocaa.launcher.framework.launcherhost.LauncherHostViewBoundaryEvent.IHostViewBoundaryEventListener;
import com.coocaa.launcher.framework.launcherhost.statusbar.StatusBarHostView;
import com.coocaa.launcher.framework.launcherhost.statusbar.StatusBarHostViewController;
import com.coocaa.launcher.framework.manager.configdata.ConfigManager;
import com.coocaa.launcher.framework.manager.configdata.data.LauncherAppItemTableData;
import com.coocaa.launcher.framework.manager.configdata.data.LauncherAppItemTableData.APP_ITEM_TYPE;
import com.coocaa.launcher.framework.manager.configdata.data.LauncherAppItemTableData.AppEntryData;
import com.coocaa.launcher.framework.manager.configdata.data.LauncherAppItemTableData.AppFolderData;
import com.coocaa.launcher.framework.manager.configdata.data.LauncherAppItemTableData.AppItemData;
import com.coocaa.launcher.framework.manager.configdata.data.LauncherAppItemTableData.AppShortCutData;
import com.coocaa.launcher.framework.manager.configdata.data.LauncherAppItemTableData.AppWidgetData;
import com.coocaa.launcher.framework.manager.configdata.data.LauncherAppItemTableData.FoldableAppData;
import com.coocaa.launcher.pattern.normal.util.LayoutExtra;
import com.coocaa.launcher.util.PathConstants;
import com.coocaa.x.app.framework.app.LiteAppApplication;
import com.coocaa.x.app.framework.utils.ConfigUtils;
import com.coocaa.x.framework.app.Container;
import com.coocaa.x.framework.utils.Android;
import com.coocaa.x.framework.utils.Cache;
import com.coocaa.x.framework.utils.LogUtils;

import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.UUID;

/**
 * TODO 不同的launcher实现不一样的LauncherHostViewController，来控制launcher的视图和数据模型
 *
 * @author lu
 * @version 2014年12月23日
 * @see 参考转向，也就是相关主题
 */
public abstract class LauncherHostViewController implements IHostViewBoundaryEventListener {
    public static class UserCustomizedFolder extends AppFolderData {
        public final static UserCustomizedFolder instance = new UserCustomizedFolder();

        public UserCustomizedFolder() {
            setId("DEFAULT_FOLDER_ITEM_ID_UserCustomizedFolder");
        }
    }

    public interface ILauncherHostViewControllerListener {
        void onCreate(LauncherHostViewController controller, List<LauncherHostPageView> views);

        void onPageViewAdded(LauncherHostViewController controller, LauncherHostPageView view);

        void onPageViewRemoved(LauncherHostViewController controller, LauncherHostPageView view);

        void onDestroy(LauncherHostViewController controller);
    }

    private class ShortCutReceiver extends BroadcastReceiver {
        public ShortCutReceiver() {
            super();
            IntentFilter filter = new IntentFilter();
            filter.addAction("com.android.launcher.action.INSTALL_SHORTCUT");
            mContext.registerReceiver(this, filter);
        }

        @Override
        public void onReceive(Context context, final Intent intent) {
            // TODO Auto-generated method stub
            Runnable run = null;
            String action = intent.getAction();
            if (action.equals("com.android.launcher.action.INSTALL_SHORTCUT")) {
                run = new Runnable() {
                    @Override
                    public void run() {
                        // TODO Auto-generated method stub
                        AppShortCutData data = new AppShortCutData();
                        data.setTitle(intent.getStringExtra(Intent.EXTRA_SHORTCUT_NAME));
                        data.setDuplicate(intent.getBooleanExtra("duplicate", false));
                        Intent shortcutIntent = intent
                                .getParcelableExtra(Intent.EXTRA_SHORTCUT_INTENT);
                        data.setIntent(shortcutIntent.toUri(0));
                        // data.setId(MD5.md5s(data.getIntent()));
                        Drawable shortcutIcon = null;
                        byte[] bis = intent.getByteArrayExtra(Intent.EXTRA_SHORTCUT_ICON);
                        if (bis != null) {
                            try {
                                Bitmap bitmap = BitmapFactory.decodeByteArray(bis, 0, bis.length);
                                shortcutIcon = new BitmapDrawable(mContext.getResources(), bitmap);
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        }
                        if (shortcutIcon == null) {
                            Parcelable iconParcel = intent
                                    .getParcelableExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE);
                            ShortcutIconResource iconRes = (ShortcutIconResource) iconParcel;
                            shortcutIntent.setPackage(iconRes.packageName);
                            try {
                                Resources resources = mContext.getPackageManager()
                                        .getResourcesForApplication(iconRes.packageName);
                                int iconid = resources.getIdentifier(iconRes.resourceName, null,
                                        null);
                                shortcutIcon = resources.getDrawable(iconid);
                            } catch (NameNotFoundException e) {
                                e.printStackTrace();
                            }
                        }
                        data.setShortcutIcon(saveDrawable(shortcutIcon, data.getId()));
                        shortcutIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE,
                                data.getShortcutIcon());
                        data.setIntent(shortcutIntent.toUri(0));
                        hostContext.addAppShortcutData(data);
                    }
                };
            }
            if (run != null)
                postAction(run);
        }
    }


    private static class SDAppReceiver extends BroadcastReceiver {
        private static SDAppReceiver instance = null;

        public static synchronized void create() {
            synchronized (mContext) {
                if (instance == null)
                    instance = new SDAppReceiver();
            }
        }

        public static synchronized void destroy() {
            synchronized (mContext) {
                if (instance != null)
                    try {
                        mContext.unregisterReceiver(instance);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                instance = null;
            }
        }

        private SDAppReceiver() {
            super();
            IntentFilter filter = new IntentFilter();
            filter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE);
            filter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);
            mContext.registerReceiver(this, filter);
        }

        @Override
        public void onReceive(Context context, Intent intent) {
            // TODO Auto-generated method stub
            String action = intent.getAction();
            final String[] packages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
            Runnable run = null;
            if (action.equals(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE)) {
                run = new Runnable() {
                    public void run() {
                        for (String pkg : packages) {
                            LogUtils.d("WWW", pkg);
                            List<AppItemData> items = hostContext.getAllItems(false);
                            for (AppItemData d : items) {
                                if (d.isInvisible())
                                    hostContext.setAppItemDataInVisiable(d, false);
                            }
                        }
                    }
                };
            } else if (action.equals(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE)) {
                run = new Runnable() {
                    public void run() {
                        if (packages != null)
                            for (String pkg : packages) {
                                List<AppEntryData> entrys = hostContext.getAppEntrys();
                                for (AppEntryData data : entrys) {
                                    if (data.getPackageName().equals(pkg))
                                        hostContext.setAppItemDataInVisiable(data, true);
//                                    hostContext.removeAppEntryData(data,
//                                            PathConstants.RemoveShortcutPath.UNPLUGIN_SDCARD
//                                                    .toString());
                                }
                            }
                        if (packages != null)
                            for (String pkg : packages) {
                                List<AppShortCutData> shortcuts = hostContext.getAppShortcuts();
                                for (AppShortCutData data : shortcuts) {
                                    if (data.getPackageName().equals(pkg))
                                        hostContext.setAppItemDataInVisiable(data, true);
//                                        hostContext.removeAppShortcutData(data);
                                }
                            }
                    }
                };
            }
            if (run != null && self != null)
                self.postAction(run);
        }
    }

    private static class PackageReceiver extends BroadcastReceiver {
        private static PackageReceiver instance = null;

        public static synchronized void create() {
            synchronized (mContext) {
                if (instance == null)
                    instance = new PackageReceiver();
            }
        }

        public static synchronized void destroy() {
            synchronized (mContext) {
                if (instance != null)
                    try {
                        mContext.unregisterReceiver(instance);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                instance = null;
            }
        }

        private PackageReceiver() {
            super();
            IntentFilter filter = new IntentFilter();
            filter.addAction("android.intent.action.PACKAGE_ADDED");
            filter.addAction("android.intent.action.PACKAGE_REMOVED");
            filter.addDataScheme("package");
            mContext.registerReceiver(this, filter);
        }

        @Override
        public void onReceive(Context context, Intent intent) {
            // TODO Auto-generated method stub
            LogUtils.d("WWW", "PackageReceiver onReceive action:" + intent.getAction());
            Runnable run = null;
            String action = intent.getAction();
            final String pkgName = intent.getDataString().substring(8);
            if (action.equals("android.intent.action.PACKAGE_ADDED")) {
                run = new Runnable() {
                    public void run() {
                        if (bNotifyPackageAdded) {
                            AppEntryData entryData = null;
                            while (entryData == null) {
                                entryData = AppEntryData.create(pkgName);
                                try {
                                    Thread.sleep(100);
                                } catch (InterruptedException e) {
                                    // TODO Auto-generated catch block
                                    e.printStackTrace();
                                }
                            }
                            hostContext.addAppEntryData(entryData,
                                    PathConstants.AddShortcutPath.INSTALL_APP.toString(), false);
                        }
                    }
                };
            } else if (action.equals("android.intent.action.PACKAGE_REMOVED")) {
                run = new Runnable() {
                    public void run() {
                        if (bNotifyPackageRemoved) {
                            List<AppEntryData> entrys = hostContext.getAppEntrys();
                            for (AppEntryData data : entrys) {
                                if (data.getPackageName().equals(pkgName))
                                    hostContext.removeAppEntryData(data,
                                            PathConstants.RemoveShortcutPath.UNINSTALL_APP
                                                    .toString());
                            }

                            List<AppShortCutData> shortcuts = hostContext.getAppShortcuts();
                            for (AppShortCutData data : shortcuts) {
                                if (data.getPackageName().equals(pkgName))
                                    hostContext.removeAppShortcutData(data);
                            }
                        }
                        hostContext.removeInvisiableAppItemWhenAppUninstalled(pkgName);
                    }
                };
            }
            if (run != null && self != null)
                self.postAction(run);
        }
    }

    protected static Context mContext = null;

    public static void setContext(Context context) {
        mContext = context;
    }

    public class LauncherHostViewContext {
        private String pattern = null;
        private Cache<String, AppItemData> allCache = new Cache<String, AppItemData>();
        private Cache<String, AppFolderData> appFolderCache = new Cache<String, AppFolderData>();
        private Cache<String, AppEntryData> appEntryCache = new Cache<String, AppEntryData>();
        private Cache<String, AppShortCutData> appShortcutCache = new Cache<String, AppShortCutData>();
        private Cache<String, AppWidgetData> appWidgetCache = new Cache<String, AppWidgetData>();

        public LauncherHostViewContext(String pattern, List<AppFolderData> folders,
                                       List<AppEntryData> entrys, List<AppShortCutData> shortcuts,
                                       List<AppWidgetData> widgets) {
            for (AppFolderData folder : folders) {
                removeTheSameLauyoutItem(folder, false);
                allCache.add(folder.getId(), folder);
                appFolderCache.add(folder.getId(), folder);
            }
            for (AppEntryData entry : entrys) {
                removeTheSameLauyoutItem(entry, false);
                allCache.add(entry.getId(), entry);
                appEntryCache.add(entry.getId(), entry);
            }
            for (AppShortCutData shortcut : shortcuts) {
                removeTheSameLauyoutItem(shortcut, false);
                allCache.add(shortcut.getId(), shortcut);
                appShortcutCache.add(shortcut.getId(), shortcut);
            }
            for (AppWidgetData widget : widgets) {
                removeTheSameLauyoutItem(widget, false);
                allCache.add(widget.getId(), widget);
                appWidgetCache.add(widget.getId(), widget);
            }
        }

        public String getCurrentPattern() {
            return pattern;
        }

        public List<AppItemData> getAllItems(boolean filerVisiable) {
            if (!filerVisiable)
                return allCache.values();
            List<AppItemData> ret = new ArrayList<AppItemData>();
            List<AppItemData> datas = allCache.values();
            for (AppItemData d : datas) {
                if (!d.isInvisible())
                    ret.add(d);
            }
            return ret;
        }

        public List<AppFolderData> getAppFolders() {
            return appFolderCache.values();
        }

        public List<AppShortCutData> getAppShortcuts() {
            return appShortcutCache.values();
        }

        public List<AppEntryData> getAppEntrys() {
            return appEntryCache.values();
        }

        public List<AppWidgetData> getAppWidgets() {
            return appWidgetCache.values();
        }

        /**
         * 移除添加到相同layout的已被隐藏的item
         *
         * @param data
         */
        private void removeTheSameLauyoutItem(AppItemData data, boolean checkInvisible) {
            List<AppItemData> datas = getAllItems(false);
            for (AppItemData d : datas) {
                try {
                    if ((checkInvisible && d.isInvisible()) || !checkInvisible) {
                        LayoutExtra l1 = LayoutExtra.parseJObject(d.getLayoutExtra(), LayoutExtra.class);
                        LayoutExtra l2 = LayoutExtra.parseJObject(data.getLayoutExtra(), LayoutExtra.class);
                        if (l1.equals(l2)) {
                            allCache.remove(d.getId());
                            appFolderCache.remove(d.getId());
                            appEntryCache.remove(d.getId());
                            appShortcutCache.remove(d.getId());
                            appWidgetCache.remove(d.getId());
                            ConfigManager.getInstance().deleteLauncherAppIntemDatas(d.getId());
                            break;
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }

        public void removeInvisiableAppItemWhenAppUninstalled(String pkgname) {
            List<AppItemData> datas = getAllItems(false);
            for (AppItemData d : datas) {
                try {
                    if (d.isInvisible() && d.getPackageName().equals(pkgname)) {
                        allCache.remove(d.getId());
                        appFolderCache.remove(d.getId());
                        appEntryCache.remove(d.getId());
                        appShortcutCache.remove(d.getId());
                        appWidgetCache.remove(d.getId());
                        ConfigManager.getInstance().deleteLauncherAppIntemDatas(d.getId());
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }

        public boolean addAppFolderData(AppFolderData data) {
            AppFolderData _data = onAppFolderAdded(data);
            if (_data != null) {
                _data.setType(APP_ITEM_TYPE.APP_FOLDER_TYPE.toString());
                removeTheSameLauyoutItem(_data, true);
                if (allCache.containsKey(_data.getId()))
                    _data.setId(UUID.randomUUID().toString());
                allCache.add(_data.getId(), _data);
                appFolderCache.add(_data.getId(), _data);
                ConfigManager.getInstance().insertLauncherAppItemData(_data.getId(),
                        APP_ITEM_TYPE.APP_FOLDER_TYPE.toString(), container.getName(),
                        _data.toString());
                return true;
            }
            return false;
        }

        public boolean removeAppFolderData(AppFolderData data) {
            boolean b = onAppFolderRemoved(data);
            if (b) {
                allCache.remove(data.getId());
                appFolderCache.remove(data.getId());
                ConfigManager.getInstance().deleteLauncherAppIntemDatas(data.getId());
            }
            return b;
        }

        public void updateAppFolderData(AppFolderData data) {
            ConfigManager.getInstance().updateLauncherAppIntemDatas(data.getId(),
                    APP_ITEM_TYPE.APP_FOLDER_TYPE.toString(), container.getName(), data.toString());
        }

        public AppFolderData getAppFolder(String id) {
            return appFolderCache.get(id);
        }

        public boolean addAppEntryData(AppEntryData data, String path, boolean binit) {
            AppEntryData _data = onAppEntryAdded(data, path, binit);
            if (_data != null) {
                _data.setType(APP_ITEM_TYPE.APP_ENTRY_TYPE.toString());
                removeTheSameLauyoutItem(_data, true);
                if (allCache.containsKey(_data.getId()))
                    _data.setId(UUID.randomUUID().toString());
                allCache.add(_data.getId(), _data);
                appEntryCache.add(_data.getId(), _data);
                ConfigManager.getInstance().insertLauncherAppItemData(_data.getId(),
                        APP_ITEM_TYPE.APP_ENTRY_TYPE.toString(), container.getName(),
                        _data.toString());
                return true;
            }
            return false;
        }

        public boolean setAppItemDataInVisiable(AppItemData data, boolean v) {
            data.setInvisible(v);
            boolean b = onAppItemInVisiableChanged(data, v);
            if (b) {
                ConfigManager.getInstance().updateLauncherAppIntemDatas(data.getId(),
                        data.getType(), container.getName(), data.toString());
            }
            return b;
        }

        public boolean removeAppEntryData(AppEntryData data, String path) {
            boolean b = onAppEntryRemoved(data, path);
            if (b) {
                allCache.remove(data.getId());
                appEntryCache.remove(data.getId());
                ConfigManager.getInstance().deleteLauncherAppIntemDatas(data.getId());
            }
            return b;
        }

        public List<AppEntryData> getAppEntryDatas() {
            return appEntryCache.values();
        }

        public boolean addAppShortcutData(AppShortCutData data) {
            AppShortCutData _data = onShortCutAdded(data);
            if (_data == null) {
                File file = new File(data.getShortcutIcon());
                if (file.exists())
                    file.delete();
                return false;
            } else {
                // if (_data.isDuplicate())
                // {
                _data.setType(APP_ITEM_TYPE.APP_SHORTCUT_TYPE.toString());
                removeTheSameLauyoutItem(_data, true);
                if (allCache.containsKey(_data.getId()))
                    _data.setId(UUID.randomUUID().toString());
                allCache.add(_data.getId(), _data);
                appShortcutCache.add(_data.getId(), _data);
                ConfigManager.getInstance().insertLauncherAppItemData(_data.getId(),
                        APP_ITEM_TYPE.APP_SHORTCUT_TYPE.toString(), container.getName(),
                        _data.toString());
                // }
                return true;
            }
        }

        public boolean removeAppShortcutData(AppShortCutData data) {
            boolean b = onShortCutRemoved(data);
            if (b) {
                allCache.remove(data.getId());
                appShortcutCache.remove(data.getId());
                ConfigManager.getInstance().deleteLauncherAppIntemDatas(data.getId());
            }
            return b;
        }

        public List<AppShortCutData> getAppShortcutDatas() {
            return appShortcutCache.values();
        }

        public boolean removeAppWidgetData(AppWidgetData data) {
            // TODO Auto-generated method stub
            boolean b = onAppWidgetRemoved(data);
            if (b) {
                allCache.remove(data.getId());
                appWidgetCache.remove(data.getId());
                ConfigManager.getInstance().deleteLauncherAppIntemDatas(data.getId());
            }
            return b;
        }

        public boolean addAppWidgetData(AppWidgetData data) {
            // TODO Auto-generated method stub
            AppWidgetData _data = onAppWidgetAdded(data);
            if (_data != null) {
                _data.setType(APP_ITEM_TYPE.APP_WIDGET_TYPE.toString());
                removeTheSameLauyoutItem(_data, true);
                if (allCache.containsKey(_data.getId()))
                    _data.setId(UUID.randomUUID().toString());
                allCache.add(_data.getId(), _data);
                appWidgetCache.add(_data.getId(), _data);
                ConfigManager.getInstance().insertLauncherAppItemData(_data.getId(),
                        APP_ITEM_TYPE.APP_WIDGET_TYPE.toString(), container.getName(),
                        _data.toString());
                return true;
            }
            return false;
        }

        public synchronized final boolean moveFoldableAppToFolder(FoldableAppData data,
                                                                  AppFolderData folder) {
            AppFolderData _folder = getAppFolder(folder.getId());
            if (_folder == null) {
                addAppFolderData(folder);
                _folder = folder;
            } else {
                if (_folder.containsChild(data))
                    return false;
            }
            _folder.addFoldableAppItem(data);
            updateAppFolderData(_folder);
            return true;
        }

        public synchronized final boolean removeFoldableAppFromFolder(FoldableAppData data,
                                                                      AppFolderData folder) {
            AppFolderData _folder = getAppFolder(folder.getId());
            if (_folder == null)
                return false;
            List<FoldableAppData> list = folder.getFoldableChilds();
            for (FoldableAppData d : list) {
                if (d.equals(data)) {
                    _folder.removeFoldableAppItem(d);
                    break;
                }
            }
            updateAppFolderData(_folder);
            return true;
        }
    }

    private static LauncherHostViewController self = null;
    private Container container = null;
    private String icon_drawable_cache_path = null;
    private ILauncherHostViewControllerListener listener = null;
    private IHostViewBoundaryEventHandler boundaryEventHandler = null;
    public static LauncherHostViewContext hostContext = null;

    private static boolean bNotifyPackageAdded = true;
    private static boolean bNotifyPackageRemoved = true;

    public LauncherHostViewController(final String pattern) {
        self = this;
        container = new Container(pattern) {
            private void initIconCache() {
                icon_drawable_cache_path = mContext.getCacheDir().getAbsolutePath()
                        + "/icon_drawable_cache";
                File file = new File(icon_drawable_cache_path);
                if (!file.exists())
                    file.mkdir();
            }

            private LauncherHostViewContext initHostContext() {
                List<AppFolderData> folders = new ArrayList<AppFolderData>();
                List<AppEntryData> entrys = new ArrayList<AppEntryData>();
                List<AppShortCutData> shortcuts = new ArrayList<AppShortCutData>();
                List<AppWidgetData> widgets = new ArrayList<AppWidgetData>();

                if (LiteAppApplication.canShowGuide()) {
                    InputStream in = null;
                    BufferedReader br = null;
                    try {
                        String line = null;
                        int pos = 0;
                        in = ConfigUtils.getCurrnetConfig("launcher_default_hotapps.config", mContext);
                        br = new BufferedReader(new InputStreamReader(in));
                        while ((line = br.readLine()) != null) {
                            JSONObject jobj = JSON.parseObject(line);
                            String mainActivity = jobj.getString("mainActivity");
                            String packageName = jobj.getString("packageName");

                            AppEntryData entry = new AppEntryData();
                            entry.setPackageName(packageName);
                            entry.setActivityName(mainActivity);
                            entry.setMainActivity(mainActivity);
                            entry.setId(UUID.randomUUID().toString());
                            entry.setTitle(Android.getNameByActivity(mContext, packageName, mainActivity));
                            entry.setType(APP_ITEM_TYPE.APP_ENTRY_TYPE.toString());
                            LayoutExtra extra = new LayoutExtra();
                            extra.setPreseted(true);
                            extra.setPosition(pos++);
                            entry.setLayoutExtra(extra.toString());
                            ConfigManager.getInstance().insertLauncherAppItemData(entry.getId(),
                                    APP_ITEM_TYPE.APP_ENTRY_TYPE.toString(), container.getName(),
                                    entry.toString());
                        }
                    } catch (Exception e1) {
                        e1.printStackTrace();
                    } finally {
                        if (in != null)
                            try {
                                in.close();
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                        if (br != null)
                            try {
                                br.close();
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                    }
                }


                List<LauncherAppItemTableData> list = ConfigManager.getInstance()
                        .getLauncherAppIntemDatasSelect(null, null, container.getName());
                Collections.reverse(list);
                boolean hasUserCustomizedItem = false;
                for (LauncherAppItemTableData data : list) {
                    if (data.getDataid().equals(UserCustomizedFolder.instance.getId()))
                        hasUserCustomizedItem = true;
                    APP_ITEM_TYPE type = data.getEnumType();
                    String json = data.getJson();
                    switch (type) {
                        case APP_FOLDER_TYPE: {
                            AppFolderData d = AppEntryData.parseJObject(json, AppFolderData.class);
                            d.setInvisible(!Android.isPackageInstalled(mContext, d.getPackageName()));
                            folders.add(d);
//                            if (Android.isPackageInstalled(mContext, d.getPackageName()))
//                                folders.add(d);
                            break;
                        }
                        case APP_ENTRY_TYPE: {
                            AppEntryData d = AppEntryData.parseJObject(json, AppEntryData.class);
                            d.setTitle(Android.getNameByActivity(mContext, d.getPackageName(), d.getActivityName()));
                            d.setInvisible(!Android.isPackageInstalled(mContext, d.getPackageName()));
                            entrys.add(d);
//                            if (Android.isPackageInstalled(mContext, d.getPackageName()))
//                                entrys.add(d);
                            break;
                        }
                        case APP_SHORTCUT_TYPE: {
                            AppShortCutData d = AppShortCutData.parseJObject(json,
                                    AppShortCutData.class);
                            d.setInvisible(!Android.isPackageInstalled(mContext, d.getPackageName()));
                            shortcuts.add(d);
//                            if (Android.isPackageInstalled(mContext, d.getPackageName()))
//                                shortcuts.add(d);
                            break;
                        }
                        case APP_WIDGET_TYPE: {
                            AppWidgetData d = AppWidgetData.parseJObject(json, AppWidgetData.class);
                            d.setInvisible(!Android.isPackageInstalled(mContext, d.getPackageName()));
                            widgets.add(d);
//                            if (Android.isPackageInstalled(mContext, d.getPackageName()))
//                                widgets.add(d);
                            break;
                        }
                        default:
                            break;
                    }
                }

                LauncherHostViewContext c = new LauncherHostViewContext(pattern, folders, entrys,
                        shortcuts, widgets);
                if (!hasUserCustomizedItem) {
                    c.addAppFolderData(UserCustomizedFolder.instance);
                }
                return c;
            }

            @Override
            protected void onCreate() {
                // TODO Auto-generated method stub
                LogUtils.i("******************************onCreate 1");
                initIconCache();
                LogUtils.i("******************************onCreate 2");
                hostContext = initHostContext();
                LogUtils.i("******************************onCreate 3");
                // new ShortCutReceiver();
                PackageReceiver.create();
                SDAppReceiver.create();
                LogUtils.i("******************************onCreate 4");

                LauncherHostViewController.this.onCreate(hostContext);
                LogUtils.i("******************************onCreate 5");
                if (listener != null)
                    listener.onCreate(LauncherHostViewController.this, inflate());
                LogUtils.i("******************************onCreate 6");
            }

            @Override
            protected void onDestroy() {
                // TODO Auto-generated method stub
                PackageReceiver.destroy();
                SDAppReceiver.destroy();
                LauncherHostViewController.this.onDestroy();
                if (listener != null)
                    listener.onDestroy(LauncherHostViewController.this);
            }
        };
    }

    protected final void enableNotifyPackageAdded(boolean b) {
        bNotifyPackageAdded = b;
    }

    protected final void enableNotifyPackageRemoved(boolean b) {
        bNotifyPackageRemoved = b;
    }

    public final void setListener(ILauncherHostViewControllerListener listener) {
        this.listener = listener;
    }

    public final void setBoundaryEventHandler(IHostViewBoundaryEventHandler boundaryEventHandler) {
        this.boundaryEventHandler = boundaryEventHandler;
    }

    public final void create() {
        container.create();
    }

    public final void destroy() {
        container.destroy();
    }

    private String saveDrawable(Drawable drawable, String filename) {
        String filePath = icon_drawable_cache_path + "/" + filename;
        ByteArrayOutputStream os = null;
        BufferedOutputStream bos = null;
        FileOutputStream fos = null;
        File file = null;
        try {
            Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap();
            os = new ByteArrayOutputStream();
            bitmap.compress(Bitmap.CompressFormat.PNG, 100, os);
            byte[] bytes = os.toByteArray();
            os.close();
            file = new File(filePath);
            if (file.exists())
                file.delete();
            fos = new FileOutputStream(file);
            bos = new BufferedOutputStream(fos);
            bos.write(bytes);
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            if (os != null)
                try {
                    os.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            if (bos != null)
                try {
                    bos.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            if (fos != null)
                try {
                    fos.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
        }
        return filePath;
    }

    protected AppFolderData onAppFolderAdded(AppFolderData data) {
        return data;
    }

    protected boolean onAppFolderRemoved(AppFolderData data) {
        return true;
    }

    /**
     * TODO 添加了快捷方式，如果实现了，则需把AppShortCutData中的布局信息补充上，由此类来完成数据的存储和更新，如果返回null，则表明当前launcher不处理快捷方式
     *
     * @param data 添加了某一个快捷方式
     * @return AppShortCutData
     * 如果为null，则表示当前launcher不处理快捷方式，如果不为空，则需要当前launcher把AppShortCutData中的layoutExtra补充完整
     * @author lu
     * @version 2014年12月23日 以修改时间为准
     */
    protected AppShortCutData onShortCutAdded(AppShortCutData data) {
        return data;
    }

    protected void onShortCutUpdate(AppShortCutData data) {

    }

    /**
     * TODO 删除某一个快捷方式
     *
     * @param data 删除了某一个快捷方式
     * @return false:当前launcher不处理删除快捷方式的动作， true：要处理
     * @author lu
     * @version 2014年12月23日 以修改时间为准
     */
    protected boolean onShortCutRemoved(AppShortCutData data) {
        return true;
    }

    protected AppEntryData onAppEntryAdded(AppEntryData data, String path, boolean binit) {
        return data;
    }

    protected boolean onAppEntryRemoved(AppEntryData data, String path) {
        return true;
    }

    protected AppWidgetData onAppWidgetAdded(AppWidgetData data) {
        return data;
    }

    protected boolean onAppWidgetRemoved(AppWidgetData data) {
        return true;
    }

    protected boolean onAppItemInVisiableChanged(AppItemData data, boolean v) {
        return false;
    }

    public final void onActivityResult(final int requestCode, final int resultCode,
                                       final Intent data) {
        Runnable run = new Runnable() {
            @Override
            public void run() {
                // TODO Auto-generated method stub
                if (resultCode == Activity.RESULT_OK) {
                    try {
                        // ComponentName comInfo = data.getComponent();
                        APP_ITEM_TYPE type = APP_ITEM_TYPE.valueOf(data
                                .getStringExtra("APP_ITEM_TYPE"));
                        // PackageManager pm = mContext.getPackageManager();
                        // ActivityInfo activityInfo = pm.getActivityInfo(comInfo,
                        // PackageManager.GET_INTENT_FILTERS);
                        switch (type) {
                            case APP_ENTRY_TYPE: {
                                AppEntryData entryData = new AppEntryData();
                                entryData.setTitle(data.getStringExtra("title"));
                                entryData.setLocalPath(data.getStringExtra("localIconPath"));
                                entryData.setIconUrl(data.getStringExtra("iconUrl"));
                                entryData.setPackageName(data.getStringExtra("packageName"));
                                entryData.setActivityName(data.getStringExtra("activityName"));
                                // entryData.setFlag(AppEntryData.FLAG_ADD_PATH_FROM_PICK_ACTIVITY);
                                hostContext.addAppEntryData(entryData,
                                        PathConstants.AddShortcutPath.PICK_ACTIVITY.toString(),
                                        false);
                                break;
                            }
                            case APP_SHORTCUT_TYPE: {
                                // String applabel = (String) activityInfo.loadLabel(pm);
                                // Drawable appIcon = activityInfo.loadIcon(pm);
                                // AppShortCutData shortCutData = new AppShortCutData();
                                // shortCutData.setTitle(applabel);
                                // shortCutData.setDuplicate(false);
                                // shortCutData.setIntent(data.toUri(0));
                                // shortCutData.setPackageName(comInfo.getPackageName());
                                // // shortCutData.setId(MD5.md5s(shortCutData.getIntent()));
                                // shortCutData.setShortcutIcon(saveDrawable(appIcon,
                                // shortCutData.getId()));
                                // hostContext.addAppShortcutData(shortCutData);
                                break;
                            }
                            case APP_WIDGET_TYPE: {
                                break;
                            }
                            default:
                                break;
                        }
                    } catch (Exception e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
        };
        postAction(run);
    }

    public final void postAction(Runnable run) {
        container.postAction(run);
    }

    public final void postAction(Runnable run, long delays) {
        container.postAction(run, delays);
    }

    protected void onCreate(LauncherHostViewContext context) {
    }

    protected void onDestroy() {
    }

    protected void setStatusBar(StatusBarHostView statusBar) {
        if (statusBar != null) {
            StatusBarHostViewController.getInstance().setStatusBarHostView(statusBar);
        } else
            LogUtils.i("The partten:" + container.getName() + " has no statusbar!!!");
    }

    protected synchronized final void addLauncherHostPageView(LauncherHostPageView view) {
        if (listener != null)
            listener.onPageViewAdded(this, view);
    }

    protected synchronized final void removeLauncherHostPageView(LauncherHostPageView view) {
        if (listener != null)
            listener.onPageViewRemoved(this, view);
    }

    protected synchronized final void commitBoundaryEvent(LauncherHostViewBoundaryEvent event,
                                                          IHostViewBoundaryEventListener listener) {
        if (listener == null)
            listener = this;
        if (boundaryEventHandler != null)
            boundaryEventHandler.onHostViewBoundaryEvent(event, listener);
    }

    @Override
    public void onHostViewBoundaryEventComplete(LauncherHostViewBoundaryEvent event) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onHostViewBoundaryEventCompleteFailed(LauncherHostViewBoundaryEvent event) {
        // TODO Auto-generated method stub

    }

    public boolean onKeyDown(int keyCode, KeyEvent event) {
        return false;
    }

    /**
     * TODO 创建当前launcher的所有pageview，在hostview中调用（非主线程）
     *
     * @return List<LauncherHostPageView> 创建的pageview列表
     * @author lu
     * @version 2014年12月23日 以修改时间为准
     * @see com.coocaa.launcher.framework.launcherhost.LauncherHostView
     */
    protected abstract List<LauncherHostPageView> inflate();
}
